package com.yummy.web.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;

import com.yummy.security.AntPathPermissionMatcher;
import com.yummy.security.PermissionMatcher;
import com.yummy.web.filter.GlobalExceptionFilter;
import com.yummy.web.security.config.SecurityProperties;
import com.yummy.web.security.config.SessionFilterProperties;
import com.yummy.web.security.context.InMemorySessionManager;
import com.yummy.web.security.context.SessionManager;
import com.yummy.web.security.filter.AuthorizationFilter;
import com.yummy.web.security.filter.PrincipalIndentificationFilter;
import com.yummy.web.security.filter.SessionFilter;

@EnableConfigurationProperties(SecurityProperties.class)
public class WebConfiguration {
	
	private Logger logger = LoggerFactory.getLogger(getClass());

	@Bean
	public FilterRegistrationBean<GlobalExceptionFilter> globalExceptionFilter(){
		FilterRegistrationBean<GlobalExceptionFilter> bean = new FilterRegistrationBean<GlobalExceptionFilter>(new GlobalExceptionFilter());
		bean.addUrlPatterns("/*");
		bean.setOrder(FilterOrdered.GLOBAL_EXCEPTION_FILTER_ORDER);
		return bean;
	}
	
	@Bean
	@ConditionalOnMissingBean(SessionManager.class)
	public SessionManager sessionManager(SecurityProperties securityProperties) {
		logger.info("cannot find SessionoManager,create default InMemorySessionManager");
		SessionFilterProperties sessionProperties = securityProperties.getSession();
		Long timeout = sessionProperties == null?null:sessionProperties.getTimeout();
		SessionManager sessionManager = new InMemorySessionManager(timeout);
		return sessionManager;
	}
	
	@Bean
	public FilterRegistrationBean<SessionFilter> sessionFilter(SecurityProperties securityProperties,SessionManager sessionManager){
		FilterRegistrationBean<SessionFilter> bean = new FilterRegistrationBean<SessionFilter>(new SessionFilter(securityProperties.getSession(),sessionManager));
		bean.addUrlPatterns("/*");
		bean.setOrder(FilterOrdered.SESSION_FILTER_ORDER);
		return bean;
	}
	
	@Bean
	public FilterRegistrationBean<PrincipalIndentificationFilter> principalIndentificationFilter(SecurityProperties securityProperties){
		FilterRegistrationBean<PrincipalIndentificationFilter> bean = new FilterRegistrationBean<PrincipalIndentificationFilter>(new PrincipalIndentificationFilter(securityProperties.getLogin()));
		bean.addUrlPatterns("/*");
		bean.setOrder(FilterOrdered.PRINCIPAL_IDENTIFICATION_FILTER_ORDER);
		return bean;
	}
	
	@Bean
	@ConditionalOnMissingBean(PermissionMatcher.class)
	public PermissionMatcher permissionMatcher() {
		PermissionMatcher matcher = new AntPathPermissionMatcher();
		return matcher;
	}
	
	@Bean
	public FilterRegistrationBean<AuthorizationFilter> authorizationFilter(SecurityProperties securityProperties,PermissionMatcher permissionMatcher){
		FilterRegistrationBean<AuthorizationFilter> bean = new FilterRegistrationBean<AuthorizationFilter>(new AuthorizationFilter(securityProperties.getAccess(),permissionMatcher));
		bean.addUrlPatterns("/*");
		bean.setOrder(FilterOrdered.AUTHORIZATION_FILTER_ORDER);
		return bean;
	}
}
